package zjc.bookkeeping.PhotoRecognition;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import android.Manifest;
import android.content.ClipData;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.provider.MediaStore;
import android.util.Log;
import android.util.Size;
import android.util.SparseArray;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import com.wang.avi.AVLoadingIndicatorView;

import org.greenrobot.eventbus.EventBus;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import zjc.bookkeeping.R;
import zjc.bookkeeping.activity.MainActivity;
import zjc.bookkeeping.api.APIManager;
import zjc.bookkeeping.tools.EventInit;

public class PhotoRecognitionActivity extends AppCompatActivity {
    String result1;
    public static final int CHOOSE_PHOTO = 2;
    ImageView picture;
    String imagePath = null;

    TextureView mPreViewView;
    HandlerThread cameraThread;
    Handler mCameraHandler;

    CameraManager cameraManager;
    android.util.Size mPreViewSize;
    android.util.Size mCaptureSize;   //最佳的拍照尺寸

    String mCameraid;
    CameraDevice mcameraDevice;
    CaptureRequest.Builder mCaptureRequestBuilder;
    CaptureRequest mCaptureRequest;
    CameraCaptureSession mcameraCaptureSession;

    ImageReader mimageReader;
    private static final SparseArray ORIENTATION = new SparseArray();

    AVLoadingIndicatorView pr_avi;
    FrameLayout pr_avi_other;

    static {
        ORIENTATION.append(Surface.ROTATION_0, 90);
        ORIENTATION.append(Surface.ROTATION_90, 0);
        ORIENTATION.append(Surface.ROTATION_180, 270);
        ORIENTATION.append(Surface.ROTATION_270, 180);
    }

    // 返回首页
    public void back(View v) {
        // Intent 去设置要跳转的页面
        Intent intent = new Intent(this, MainActivity.class);
        // 进行跳转
        startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photo_recognition);
        Button btnChoosePhoto = (Button) findViewById(R.id.choose_photo);

        Toast.makeText(PhotoRecognitionActivity.this, "若要使用批量图像识别，请选择同一类型的小票。", Toast.LENGTH_SHORT).show();
        pr_avi=(AVLoadingIndicatorView)findViewById(R.id.pr_avi);
        pr_avi_other=findViewById(R.id.pr_avi_other);
        pr_avi_other.setVisibility(View.VISIBLE);
        pr_avi.hide();

        mPreViewView = findViewById(R.id.textureview);
        // 调用系统相册按钮的点击事件
        btnChoosePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                pr_avi_other.setVisibility(View.GONE);
                pr_avi.show();
                openAlbum();
            }
        });
    }


     //请求调用系统相册的权限
//    private void requestPermissino() {
//        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
//        } else {
//            openAlbum();
//        }
//
//    }


    // 调用系统相册
    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);//可选多张
        startActivityForResult(intent, CHOOSE_PHOTO); //打开相册
    }

    // 调用相册选择图片后
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case CHOOSE_PHOTO:
                if (resultCode == RESULT_OK) {
                    ContentResolver resolver = getContentResolver();
                    if (data.getData() != null) {//单选
                        Bitmap bitmap = null;
                        Uri uri = data.getData();
                        try {
                            bitmap = MediaStore.Images.Media.getBitmap(resolver, uri);//获得图片
                            Intent intent = new Intent(PhotoRecognitionActivity.this, addPhotoConsumptionActivity.class);
                            //intent.putExtra("bitmap", bitmap);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        byte[] bytes = Bitmap2Bytes(bitmap);
                        Log.i("1.bytes数组", String.valueOf(bytes));
                        new Thread() {
                            @Override
                            public void run() {
                                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                                byte[] img_base64=APIManager.PictureRect(bytes);
                                Log.i("2.系统相册处理结果img_base64", String.valueOf(img_base64));
                                Intent intent = new Intent(PhotoRecognitionActivity.this, TClassificationSelectionActivity.class);
                                //intent.putExtra("data", img_base64);
                                //延时发送数据
                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        try {
                                            Thread.sleep(500);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                        EventBus.getDefault().post(new EventInit(0,img_base64));
                                    }
                                }).start();
                                startActivity(intent);
                            }
                        }.start();


                    } else {//多选
                        Log.e("多选","suc");
                        List<Bitmap> bitmaps = new ArrayList<>();
                        List<String> fileList = new ArrayList<>();
                        List<String> results = new ArrayList<>();
                        ClipData imageNames = data.getClipData();
                        Log.i("data", String.valueOf(data));
                        Log.i("image", String.valueOf(imageNames));
                        List<byte[]> imgs = new ArrayList<>();
                        Intent intent = new Intent(PhotoRecognitionActivity.this, TClassificationSelectionActivity.class);
                        if (imageNames != null) {
                        for (int i = 0; i < imageNames.getItemCount(); i++) {
                            Uri imageUri = imageNames.getItemAt(i).getUri();
                            fileList.add(imageUri.toString());
                            try {
                                bitmaps.add(MediaStore.Images.Media.getBitmap(resolver,imageUri));
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            System.out.println(imageUri);
                            byte[] bytes = Bitmap2Bytes(bitmaps.get(i));
                            new Thread() {
                                @Override
                                public void run() {
                                    byte[] img_base64=APIManager.PictureRect(bytes);
                                    imgs.add(img_base64);
                                    Log.i("系统相册处理结果", String.valueOf(img_base64));
                                }
                            }.start();
                        }
                            new Thread(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        Thread.sleep(500);
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }
                                    Log.e("多选","发送");
                                    EventBus.getDefault().postSticky(new EventInit(1,imgs));
                                   // EventBus.getDefault().post(new EventInit(1,imgs));
                                }
                            }).start();
                            startActivity(intent);
                    }

                    }
                }

        }
    }

    // 将图片转换为二进制格式
    private byte[] Bitmap2Bytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
        return baos.toByteArray();
    }

    //实现具体功能
    @Override
    protected void onResume() {
        super.onResume();

        startCameraThread();
        if (!mPreViewView.isAvailable()) {
            mPreViewView.setSurfaceTextureListener(textureListener);
        } else {
            startPreView();
        }
    }

    TextureView.SurfaceTextureListener textureListener = new TextureView.SurfaceTextureListener() {
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
            //当SurfaceTexture可用时，设置相机的参数，打开摄像头
            setupCamera(i, i1);
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

        }
    };

    //设置摄像头的参数
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void setupCamera(int width, int height) {
        cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

        //拿到摄像头的id
        try {
            for (String cameraID : cameraManager.getCameraIdList()) {
                CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraID);

                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    continue;
                }
                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);

                //找到摄像头能够输出的最符合能够显示界面分辨率的最小值
                if (map != null) {
//                   mPreViewSize=getOptimalSize(map.getOutputSizes(SurfaceTexture.class),width,height);
                    mCaptureSize = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new Comparator<Size>() {
                        @Override
                        public int compare(android.util.Size size, android.util.Size t1) {
                            return Long.signum(size.getWidth() * size.getHeight() - t1.getWidth() * t1.getHeight());
                        }
                    });
                }

                //建立图片缓冲区
                setupImageReader();

                mCameraid = cameraID;
                break;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private Size getOptimalSize(Size[] sizeMap, int width, int height) {
        List<Size> sizeList = new ArrayList<Size>();

        for (Size option : sizeMap) {
            if (width > height) {  //横屏
                sizeList.add(option);
            } else {
                sizeList.add(option);
            }
        }

        if (sizeList.size() > 1) {
//            return Collections.min(sizeList, new Comparator<Size>() {
//                @Override
//                public int compare(android.util.Size size, android.util.Size t1) {
//                   return Long.signum();
//                }
//            })  ;
        }

        return sizeMap[0];
    }

    //打开摄像头
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void openCamera() {

        String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};

        int i = 0;
        for (String permission : permissions) {
            if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                this.requestPermissions(permissions, i++);
            }
        }

        try {
            cameraManager.openCamera(mCameraid, mStateCallBack, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    CameraDevice.StateCallback mStateCallBack = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            mcameraDevice = cameraDevice;
            startPreView();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {
            mcameraDevice.close();
            mcameraDevice = null;
        }

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int i) {
            mcameraDevice.close();
            mcameraDevice = null;
        }
    };

    //开始预览
    private void startPreView() {
        //建立图形缓冲区
        SurfaceTexture surfaceTexture = mPreViewView.getSurfaceTexture();
        surfaceTexture.setDefaultBufferSize(mPreViewView.getWidth(), mPreViewView.getHeight());

        //得到界面的显示对象
        Surface previewSurface = new Surface(surfaceTexture);
        try {
            mCaptureRequestBuilder = mcameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mCaptureRequestBuilder.addTarget(previewSurface);

            //建立通道
            mcameraDevice.createCaptureSession(Arrays.asList(previewSurface, mimageReader.getSurface()), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                    try {
                        mCaptureRequest = mCaptureRequestBuilder.build();
                        mcameraCaptureSession = cameraCaptureSession;
                        mcameraCaptureSession.setRepeatingRequest(mCaptureRequest, null, mCameraHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {

                }
            }, mCameraHandler);

        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }

    //打开摄像头的线程
    private void startCameraThread() {
        cameraThread = new HandlerThread("CameraThread");
        cameraThread.start();
        mCameraHandler = new Handler(cameraThread.getLooper());
    }


    //开始拍照
    public void capture(View view) {
        //获取摄像头的请求
        CaptureRequest.Builder mCameraBuilder = null;
        try {
            mCameraBuilder = mcameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
        mCameraBuilder.addTarget(mimageReader.getSurface());

        //获取摄像头方向
        int rotation = getWindowManager().getDefaultDisplay().getRotation();

        //设置拍照方向
        mCameraBuilder.set(CaptureRequest.JPEG_ORIENTATION, (Integer) ORIENTATION.get(rotation));
        CameraCaptureSession.CaptureCallback mCaptureCallBack = new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {

                Toast.makeText(getApplicationContext(), "拍照结束", Toast.LENGTH_LONG).show();
                unLockFocus();
                super.onCaptureCompleted(session, request, result);
//                Intent intent = new Intent(PhotoRecognitionActivity.this, addPhotoConsumptionActivity.class);
//                intent.putExtra("values", result1);
//                startActivity(intent);


            }
        };

        try {
            mcameraCaptureSession.stopRepeating();
            mcameraCaptureSession.capture(mCameraBuilder.build(), mCaptureCallBack, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

        //获取图像的缓冲区


        //获取文件的存储权限及操作


    }

    private void unLockFocus() {
        try {
            mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            mcameraCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(), null, mCameraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    //建立图片缓冲区
    private void setupImageReader() {
        mimageReader = ImageReader.newInstance(mCaptureSize.getWidth(), mCaptureSize.getHeight(), ImageFormat.JPEG, 2);
        mimageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
            @Override
            public void onImageAvailable(ImageReader imageReader) {
                mCameraHandler.post(new ImageSaver(imageReader.acquireLatestImage()));
            }
        }, mCameraHandler);
    }

    ;

    private class ImageSaver implements Runnable {

        Image mimage;

        public ImageSaver(Image image) {
            mimage = image;
        }

        @Override
        public void run() {
            PhotoRecognitionActivity.this.runOnUiThread(new Runnable() {
                public void run() {
                    pr_avi_other.setVisibility(View.GONE);
                    pr_avi.show();
                }
            });


            ByteBuffer buffer = mimage.getPlanes()[0].getBuffer();
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            new Thread() {
                @Override
                public void run() {
                    byte[] img_base64=APIManager.PictureRect(data);
                    Log.i("系统相册处理结果img_base64", String.valueOf(img_base64));
                    Intent intent = new Intent(PhotoRecognitionActivity.this, TClassificationSelectionActivity.class);
                    //延时发送数据
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            EventBus.getDefault().post(new EventInit(0,img_base64));
                        }
                    }).start();
                    startActivity(intent);
                }
            }.start();

        }
    }
}